package com.hnas.trade.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.hnas.account.orm.Account;
import com.hnas.account.service.AccountService;
import com.hnas.activity.domain.ActivityType;
import com.hnas.activity.orm.Activity;
import com.hnas.activity.orm.ActivityItem;
import com.hnas.activity.util.ActivityUtil;
import com.hnas.api.domain.RouteFinalValue;
import com.hnas.api.interfacebeans.SearchRecgPayInfoForm;
import com.hnas.api.interfacebeans.SearchRecgPayInfoReceive;
import com.hnas.api.server.PostConnServer;
import com.hnas.common.util.CommonConstants;
import com.hnas.common.util.CommonUtils;
import com.hnas.core.util.DateUtil;
import com.hnas.core.util.StringUtil;
import com.hnas.eastsquare.orm.SediBalanceChangeRecord;
import com.hnas.eastsquare.orm.SedimentaryBalance;
import com.hnas.eastsquare.service.SediBalanceChangeRecordService;
import com.hnas.eastsquare.service.SediToBalanceRecordService;
import com.hnas.eastsquare.service.SedimentaryBalanceService;
import com.hnas.eastsquare.util.JedisPoolUtil;
import com.hnas.ecard.domain.CardMarkConstant;
import com.hnas.ecard.domain.ECardStatus;
import com.hnas.ecard.domain.SaleCardStateEnum;
import com.hnas.ecard.intf.CoreQuerySaleCardOut;
import com.hnas.ecard.orm.AccECard;
import com.hnas.ecard.service.AccECardService;
import com.hnas.ecard.service.SaleCardOrderDetailService;
import com.hnas.ecard.service.dto.DTOSaleCardOrder;
import com.hnas.ecard.service.dto.DTOSaleCardOrderDetail;
import com.hnas.ecard.service.dto.DTOSaleCardRecord;
import com.hnas.trade.domain.OrderScheduleErrMsg;
import com.hnas.trade.domain.OrderStatus;
import com.hnas.trade.domain.OrderType;
import com.hnas.trade.domain.PayStatus;
import com.hnas.trade.domain.RechargeStatus;
import com.hnas.trade.domain.TradeRemindThread;
import com.hnas.trade.domain.TranState;
import com.hnas.trade.interfbean.GetTranInfoByOrderNoIn;
import com.hnas.trade.interfbean.GetTranInfoByOrderNoOut;
import com.hnas.trade.orm.CheckOrderRecord;
import com.hnas.trade.orm.OrderDetail;
import com.hnas.trade.orm.TradeRecord;
import com.hnas.trade.orm.TradeRecordDetail;
import com.hnas.trade.service.CheckOrderRecordService;
import com.hnas.trade.service.NewCheckOrderTaskService;
import com.hnas.trade.service.OrderDetailService;
import com.hnas.trade.service.OrderService;
import com.hnas.trade.service.TradeRecordDetailService;
import com.hnas.trade.service.TradeRecordService;
import com.hnas.trade.service.dto.DTOOrder;
import com.hnas.trade.service.dto.DTOTradeRecord;
import com.hnas.trade.service.dto.intf.TranUserQRCodeByHttpForm;

import redis.clients.jedis.Jedis;

@Component("checkOrderStatusTaskService")
public class NewCheckOrderTaskServiceImpl implements NewCheckOrderTaskService {

	private static final int COUNT_LIMIT = 3;
	
	private static Log log = LogFactory.getLog(NewCheckOrderTaskServiceImpl.class);
	
	@Value("#{component['east_square_mrch_id']}")//最低消费
	private String eastSquareMrchId;

	@Autowired
	private OrderService orderService;
	@Autowired
	private OrderDetailService orderDetailService;

	@Autowired
	private TradeRecordService tradeRecordService;

	@Autowired
	private TradeRecordDetailService tradeRecordDetailService;
	@Autowired
	private AccountService accountService;
	@Autowired
	private PostConnServer postConnServerNew;
	@Autowired
	private CheckOrderRecordService checkOrderRecordService;
	
	@Autowired
	private SediBalanceChangeRecordService sediBalanceChangeRecordService;
	@Autowired
	private SedimentaryBalanceService sedimentaryBalanceService;
	@Autowired
	private SediToBalanceRecordService sediToBalanceRecordService; 
	//@Autowired
	//private JedisUtil jedisUtil;
	@Autowired
	private JedisPoolUtil jedisPoolUtil;
	@Autowired
	private AccECardService accECardService;
	@Autowired
	private SaleCardOrderDetailService saleCardOrderDetailService;
	
	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
	
	@Value("#{component['merchant_id']}")
	private String merchantId;
	@Value("#{component['card_type']}")
	private String cardType;

	public void checkOrderStatus() {
		// 查处所有订单状态为Unpay,Paying,PayFail的订单
		List<DTOOrder> orderList = this.orderService.getUnSuccessOrderList();
		List<DTOOrder> vipList = new ArrayList<DTOOrder>();// 购买vip订单列表
		List<DTOOrder> rechargeList = new ArrayList<DTOOrder>();// 充值订单列表
		List<DTOOrder> payList = new ArrayList<DTOOrder>();// 付款订单列表
		List<DTOOrder> scanList = this.orderService.getScanMrchPayingOrderList();// 扫商户二维码订单列表
		for (DTOOrder o : orderList) {
			if (OrderType.BuyGasolineVip.getType().equals(o.getOrderType())) {
				vipList.add(o);
			} else if (OrderType.Recharge.getType().equals(o.getOrderType())) {
				rechargeList.add(o);
			} else if (OrderType.BuyGasoline.getType().equals(o.getOrderType())||OrderType.TKLinkNetTrade.getType().equals(o.getOrderType())) {
				payList.add(o);//联机交易&贴卡联机交易
			}
		}
		checkPosPay(payList);
		checkRecharge(rechargeList);
		checkScanMrch(scanList);
		List<DTOSaleCardOrder> saleCardList = this.orderService.listOrderNoPay();//电子卡购卡支付中订单
		checkSaleCard(saleCardList);
	}
	/**
	 * 检查拉卡啦POS消费的订单
	 * 
	 * @param payList
	 */
	private void checkPosPay(List<DTOOrder> payList) {
		// ----2查出付款订单失败的，
		// 1)根据交易流水号trade_sno去调用外围系统接口查询核心交易状态，如果成功的，就修改订单状态，保存交易记录和交易详情
		System.out.println("pay before:" + sdf.format(new Date())+",count:"+(payList==null?0:payList.size()));
		for (DTOOrder o : payList) {
			//根据订单号查询核心交易状态
			GetTranInfoByOrderNoIn form = new GetTranInfoByOrderNoIn();
			form.setOrderNo(o.getOrderNo());
			List<GetTranInfoByOrderNoOut> tranList = postConnServerNew.getListResultData(form, RouteFinalValue.APP_GetTranInfoByOrdNum, GetTranInfoByOrderNoOut.class);
			if(tranList == null){
				//调用接口异常
				log.info("根据订单号查询核心交易信息接口调用失败！");
				continue;
			}
			if(tranList.size() <= 0){
				checkConsumeOrder(o);
				continue;
			}
			Activity activity = postConnServerNew.getActivity(o.getMrchId(), o.getTermNo(), o.getSubId());
			if(activity != null && ActivityUtil.hasRandomDerateActivity(activity.getActivityItem())){
				GetTranInfoByOrderNoOut tranInfo = tranList.get(0);
				String tradeSno = tranInfo.getTranSno();
				if (StringUtil.isNotEmpty(tradeSno)) {
					if (TranState.Normal.getState().equals(tranInfo.getTranState())) {
						// 支付成功了的话，(判断交易记录是否成功，如果成功不改，如果不是成功，修改订单状态，并保存交易记录)
						o.setTradeSno(tradeSno);
						o.setOrderStatus(OrderStatus.Payed.getStatus());
						o.setPayStatus(PayStatus.Payed.getStatus());
						o.setUpdateTime(DateUtil.dateTimeToString(new Date()));
						o.setRemark(OrderScheduleErrMsg.getErrMsg(OrderScheduleErrMsg.PAY_SUCCESS));
						o.setPayEndTime(DateUtil.dateTimeToString(CommonUtils.getTranTime(tranInfo.getTranDate(), tranInfo.getTranTime())));
						o.setTradeEndTime(DateUtil.dateTimeToString(new Date()));
						try {
							this.orderService.saveOrUpdate(o);
						} catch (Exception e1) {
							e1.printStackTrace();
							continue;
						}
						Account account = this.accountService.findById(o.getAccId());
						JSONObject remindData = new JSONObject();
						remindData.put("openIdStr", account.getOpenId());
						remindData.put("modelType", "1");
						remindData.put("payValue", "￥"+o.getRealPay()/100.0);
						remindData.put("cardNo", o.getCardNo());
						remindData.put("tranSno", o.getOrderNo());
						remindData.put("tranTime", o.getTradeEndTime());
						remindData.put("mrchName", o.getMrchName());
						remindData.put("first", CommonConstants.FIRST_3);
						remindData.put("remark", CommonConstants.REMARK_1);
						TradeRemindThread tradeRemind = new TradeRemindThread(remindData);
						Thread thread = new Thread(tradeRemind);
						thread.start();
						// 保存交易记录
						DTOTradeRecord trDto = new DTOTradeRecord();
						BeanUtils.copyProperties(o, trDto);
						trDto.setId(CommonUtils.getUUID());
						try {
							this.tradeRecordService.saveOrUpdate(trDto);
						} catch (Exception e1) {
							e1.printStackTrace();
							continue;
						}
						this.sedimentaryBalanceService.updateByOrderNo(o.getOrderNo(), 1000*100L);
						// 保存交易详情
						List<OrderDetail> detailList = this.orderDetailService.findByOrderNo(o.getOrderNo());
						if (detailList != null && detailList.size() > 0) {
							TradeRecordDetail trd = null;
							for (OrderDetail od : detailList) {
								trd = new TradeRecordDetail();
								BeanUtils.copyProperties(od, trd);
								try {
									this.tradeRecordDetailService.save(trd);
								} catch (Exception e) {
									e.printStackTrace();
									continue;
								}
							}
						}
					} else {
						checkConsumeOrder(o);
					}
	
				} else {
					checkConsumeOrder(o);
				}
			}else{
				GetTranInfoByOrderNoOut tranInfo = tranList.get(0);
				String tradeSno = tranInfo.getTranSno();
				if (StringUtil.isNotEmpty(tradeSno)) {
					if (TranState.Normal.getState().equals(tranInfo.getTranState())) {
						// 支付成功了的话，(判断交易记录是否成功，如果成功不改，如果不是成功，修改订单状态，并保存交易记录)
						o.setTradeSno(tradeSno);
						o.setOrderStatus(OrderStatus.Payed.getStatus());
						o.setPayStatus(PayStatus.Payed.getStatus());
						o.setUpdateTime(DateUtil.dateTimeToString(new Date()));
						o.setRemark(OrderScheduleErrMsg.getErrMsg(OrderScheduleErrMsg.PAY_SUCCESS));
						o.setPayEndTime(DateUtil.dateTimeToString(CommonUtils.getTranTime(tranInfo.getTranDate(), tranInfo.getTranTime())));
						o.setTradeEndTime(DateUtil.dateTimeToString(new Date()));
						try {
							this.orderService.saveOrUpdate(o);
						} catch (Exception e1) {
							e1.printStackTrace();
							continue;
						}
						Account account = this.accountService.findById(o.getAccId());
						JSONObject remindData = new JSONObject();
						remindData.put("openIdStr", account.getOpenId());
						remindData.put("modelType", "1");
						remindData.put("payValue", "￥"+o.getRealPay()/100.0);
						remindData.put("cardNo", o.getCardNo());
						remindData.put("tranSno", o.getOrderNo());
						remindData.put("tranTime", o.getTradeEndTime());
						remindData.put("mrchName", o.getMrchName());
						remindData.put("first", CommonConstants.FIRST_3);
						remindData.put("remark", CommonConstants.REMARK_1);
						TradeRemindThread tradeRemind = new TradeRemindThread(remindData);
						Thread thread = new Thread(tradeRemind);
						thread.start();
						// 修改代金券状态
						// 保存交易记录
						DTOTradeRecord trDto = new DTOTradeRecord();
						BeanUtils.copyProperties(o, trDto);
						trDto.setId(CommonUtils.getUUID());
						try {
							this.tradeRecordService.saveOrUpdate(trDto);
						} catch (Exception e1) {
							e1.printStackTrace();
							continue;
						}
						// 保存交易详情
						// 商户扫描二维码交易
						try {
							TranUserQRCodeByHttpForm form3 = new TranUserQRCodeByHttpForm();
							form3.setQrcodeNo(o.getQrcodeNo());
							form3.setActTranAmt(o.getRealPay()+"");
							form3.setBalance(o.getAfterTradeBalance());
							form3.setMerchantId(o.getMrchId());
							form3.setPsamId(o.getPsamId());
							form3.setShopName(o.getMrchName());
							form3.setShopType(o.getMrchType());
							form3.setShouldTranAmt(o.getNeedPay()+"");
							form3.setSubCode(o.getSubId());
							form3.setTranRemark(o.getRemark());
							form3.setSwiftNumber(o.getTradeSno());
							postConnServerNew.getResultData(form3, RouteFinalValue.APP_TranUserQRCodeByHttp, JSONObject.class);
						} catch (Exception e) {
							e.printStackTrace();
						}
						
					} else {
						checkConsumeOrder(o);
					}
	
				} else {
					checkConsumeOrder(o);
				}
			}
		}
		// 查询出所有失败
		System.out.println("pay after:" + sdf.format(new Date()));
	}

	/**
	 * 检查充值的订单
	 * 
	 * @param rechargeList
	 */
	private void checkRecharge(List<DTOOrder> rechargeList) {
		// ----查出充值订单失败的
		// 1)如果有trade_sno，根据trade_sno去调用外围系统接口查询核心交易状态，如果成功的，就修改订单状态，保存交易记录；
		// 2)如果没有trade_sno,根据swift_number去调用外围系统查询微信支付结果。如果成功，就修改订单状态，保存交易记录；
		// 3)如果失败，且返回rechargeNum，再根据rechargeNum作为trade_sno去调用外围系统接口查询核心交易状态,如果成功，就修改订单状态，保存交易记录。(?)
		System.out.println("recharge before:" + sdf.format(new Date())+",count:"+(rechargeList==null?0:rechargeList.size()));
		//查出处于支付中或者未支付的充值订单，先查微信支付状态；再查核心交易状态
		for(DTOOrder o : rechargeList){
			String swiftNumber = o.getSwiftNumber();
			if (StringUtil.isEmpty(swiftNumber)) {//如果微信的流水号都没有，说明充值创建订单失败或者尚未完成订单创建
				checkRechargeOrder(o);
			}else{//说明充值订单已经创建好了
				//先查询微信的支付状态，再查询核心的交易状态
				SearchRecgPayInfoForm form = new SearchRecgPayInfoForm();
				form.setSwiftNumber(swiftNumber);
				try {
					SearchRecgPayInfoReceive searchRecgPayInfoReceive = postConnServerNew.getResultData(form, RouteFinalValue.APP_RechargeQuery, SearchRecgPayInfoReceive.class);//根据微信订单号查询微信支付结果
					if(searchRecgPayInfoReceive == null){
						checkRechargeOrder(o);
						continue;
					}
					String payStatus = searchRecgPayInfoReceive.getTradeState();//微信支付状态
					String rechargeStatus = searchRecgPayInfoReceive.getRechargeStatus();//核心的交易状态
					if(PayStatus.Unpay.equals(payStatus)){//微信未支付
						checkRechargeOrder(o);
					}else if(PayStatus.Payed.equals(payStatus)){//微信支付成功
						o.setPayStatus(payStatus);
						if(RechargeStatus.Recharged.equals(rechargeStatus)){//核心充值成功
							// 支付成功了的话，(判断交易记录是否成功，如果成功不改，如果不是成功，修改订单状态，并保存交易记录)
							o.setTradeSno(searchRecgPayInfoReceive.getRechargeNum());//订单状态改为交易成功
							o.setOrderStatus(OrderStatus.Payed.getStatus());
							o.setPayStatus(PayStatus.Payed.getStatus());
							o.setUpdateTime(DateUtil.dateTimeToString(new Date()));
							o.setRemark(OrderScheduleErrMsg.getErrMsg(OrderScheduleErrMsg.PAY_SUCCESS));
							o.setPayEndTime(searchRecgPayInfoReceive.getTransTime());
							o.setTradeEndTime(DateUtil.dateTimeToString(new Date()));
							this.orderService.saveOrUpdate(o);
							Account account = this.accountService.findById(o.getAccId());
							JSONObject remindData = new JSONObject();
							remindData.put("openIdStr", account.getOpenId());
							remindData.put("modelType", "1");
							remindData.put("payValue", "￥"+o.getRealPay()/100.0);
							remindData.put("cardNo", o.getCardNo());
							remindData.put("tranSno", o.getOrderNo());
							remindData.put("tranTime", o.getTradeEndTime());
							remindData.put("mrchName", o.getMrchName());
							remindData.put("first", CommonConstants.FIRST_2);
							remindData.put("remark", CommonConstants.REMARK_1);
							TradeRemindThread tradeRemind = new TradeRemindThread(remindData);
							Thread thread = new Thread(tradeRemind);
							thread.start();
							// 保存交易记录
							DTOTradeRecord trDto = new DTOTradeRecord();
							BeanUtils.copyProperties(o, trDto);
							trDto.setId(CommonUtils.getUUID());
							this.tradeRecordService.saveOrUpdate(trDto);
						}else if(RechargeStatus.UnRecharge.equals(rechargeStatus)){//核心交易未充值
							checkRechargeOrder(o);
						}
						
					}
				}catch(Exception e){
					e.printStackTrace();
				}
			}
		}
		System.out.println("recharge after:" + sdf.format(new Date()));
	}
	
	private void checkScanMrch(List<DTOOrder> scanList) {
		System.out.println("scanMrch before:" + sdf.format(new Date())+",count:"+(scanList==null?0:scanList.size()));
		for (DTOOrder o : scanList) {
			//根据订单号查询核心交易状态
			GetTranInfoByOrderNoIn form = new GetTranInfoByOrderNoIn();
			form.setOrderNo(o.getOrderNo());
			List<GetTranInfoByOrderNoOut> tranList = postConnServerNew.getListResultData(form, RouteFinalValue.APP_GetTranInfoByOrdNum, GetTranInfoByOrderNoOut.class);
			if(tranList == null){
				//调用接口异常
				log.info("根据订单号查询核心交易信息接口调用失败！");
				continue;
			}
			if(tranList.size() <= 0){
				checkConsumeOrder(o);
				continue;
			}
			GetTranInfoByOrderNoOut tranInfo = tranList.get(0);
			String tradeSno = tranInfo.getTranSno();
			if (StringUtil.isNotEmpty(tradeSno)) {
				if (TranState.Normal.getState().equals(tranInfo.getTranState())) {
					// 支付成功了的话，(判断交易记录是否成功，如果成功不改，如果不是成功，修改订单状态，并保存交易记录)
					o.setTradeSno(tradeSno);
					o.setOrderStatus(OrderStatus.Payed.getStatus());
					o.setPayStatus(PayStatus.Payed.getStatus());
					o.setUpdateTime(DateUtil.dateTimeToString(new Date()));
					o.setRemark(OrderScheduleErrMsg.getErrMsg(OrderScheduleErrMsg.PAY_SUCCESS));
					o.setPayEndTime(DateUtil.dateTimeToString(CommonUtils.getTranTime(tranInfo.getTranDate(), tranInfo.getTranTime())));
					o.setTradeEndTime(DateUtil.dateTimeToString(new Date()));
					try {
						this.orderService.saveOrUpdate(o);
					} catch (Exception e1) {
						e1.printStackTrace();
						continue;
					}
					Account account = this.accountService.findById(o.getAccId());
					JSONObject remindData = new JSONObject();
					remindData.put("openIdStr", account.getOpenId());
					remindData.put("modelType", "1");
					remindData.put("payValue", "￥"+o.getRealPay()/100.0);
					remindData.put("cardNo", o.getCardNo());
					remindData.put("tranSno", o.getOrderNo());
					remindData.put("tranTime", o.getTradeEndTime());
					remindData.put("mrchName", o.getMrchName());
					remindData.put("first", CommonConstants.FIRST_3);
					remindData.put("remark", CommonConstants.REMARK_1);
					TradeRemindThread tradeRemind = new TradeRemindThread(remindData);
					Thread thread = new Thread(tradeRemind);
					thread.start();
					// 修改代金券状态
					// 保存交易记录
					DTOTradeRecord trDto = new DTOTradeRecord();
					BeanUtils.copyProperties(o, trDto);
					trDto.setId(CommonUtils.getUUID());
					try {
						this.tradeRecordService.saveOrUpdate(trDto);
					} catch (Exception e1) {
						e1.printStackTrace();
						continue;
					}
					// 保存交易详情
				} else {
					checkConsumeOrder(o);
				}

			} else {
				checkConsumeOrder(o);
			}
		}
		// 查询出所有失败
		System.out.println("pay scanMrch:" + sdf.format(new Date()));
	}

	/**
	 * 检查充值订单状态
	 * @param order
	 */
	private void checkRechargeOrder(DTOOrder order){
		CheckOrderRecord checkRecord = checkOrderRecordService.findByOrderNo(order.getOrderNo());
		if(checkRecord == null){
			checkRecord = new CheckOrderRecord();
			checkRecord.setCheckCount(1);
			checkRecord.setCheckTime(DateUtil.dateTimeToString(new Date()));
			checkRecord.setId(CommonUtils.getUUID());
			checkRecord.setOrderNo(order.getOrderNo());
			try {
				checkOrderRecordService.saveOrUpdate(checkRecord);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}else{
			if(checkRecord.getCheckCount() >= COUNT_LIMIT){//次数大于等于3，处理为失败
				order.setPayStatus(PayStatus.Unpay.getStatus());//微信未支付
				order.setOrderStatus(OrderStatus.PayFail.getStatus());//订单交易失败
				order.setUpdateTime(DateUtil.dateTimeToString(new Date()));
				order.setRemark(OrderScheduleErrMsg.getErrMsg(OrderScheduleErrMsg.PAY_FAIL));
				try {
					this.orderService.saveOrUpdate(order);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}else{
				checkRecord.setCheckTime(DateUtil.dateTimeToString(new Date()));
				checkRecord.setCheckCount(checkRecord.getCheckCount()+1);
				try {
					checkOrderRecordService.saveOrUpdate(checkRecord);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * 检查消费订单状态
	 * @param order
	 */
	private void checkConsumeOrder(DTOOrder order){
		//无结果，先查次数，如果大于等于3，处理为失败；如果小于3，次数+1，状态不变；
		CheckOrderRecord checkRecord = checkOrderRecordService.findByOrderNo(order.getOrderNo());
		if(checkRecord == null){
			checkRecord = new CheckOrderRecord();
			checkRecord.setCheckCount(1);
			checkRecord.setCheckTime(DateUtil.dateTimeToString(new Date()));
			checkRecord.setId(CommonUtils.getUUID());
			checkRecord.setOrderNo(order.getOrderNo());
			try {
				checkOrderRecordService.saveOrUpdate(checkRecord);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}else{
			if(checkRecord.getCheckCount() >= COUNT_LIMIT){//次数大于等于3，处理为失败
				order.setOrderStatus(OrderStatus.PayFail.getStatus());
				order.setUpdateTime(DateUtil.dateTimeToString(new Date()));
				order.setRemark(OrderScheduleErrMsg.getErrMsg(OrderScheduleErrMsg.CORE_TRADE_SNO_EMPTY));
				try {
					this.orderService.saveOrUpdate(order);
				} catch (Exception e) {
					e.printStackTrace();
				}
				Activity activity = postConnServerNew.getActivity(order.getMrchId(), order.getTermNo(), order.getSubId());
				if(activity != null && ActivityUtil.hasRandomDerateActivity(activity.getActivityItem())){
					dealEastSquareFailOrder(order);
				}else{
					dealFailOrder(activity,order.getOrderNo());
				}
				
			}else{
				checkRecord.setCheckTime(DateUtil.dateTimeToString(new Date()));
				checkRecord.setCheckCount(checkRecord.getCheckCount()+1);
				try {
					checkOrderRecordService.saveOrUpdate(checkRecord);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 处理东方广场支付失败订单
	 * @param order
	 */
	private void dealEastSquareFailOrder(DTOOrder order) {
//		Jedis jedis = jedisUtil.getJedis();
		Jedis jedis = jedisPoolUtil.getJedis();
		SediBalanceChangeRecord changeRecord = this.sediBalanceChangeRecordService.findByOrderNo(order.getOrderNo());//
		if(changeRecord == null) {
			System.out.println("交易失败处理，根据订单号查询减免记录为空！");
		}else{
			try{
				Long balance = jedis.incrBy("balance", changeRecord.getBalanceChange());
				Long sedimentary = jedis.decrBy("sedimentary", changeRecord.getSedimentaryChange());
				SedimentaryBalance findSingleResult = this.sedimentaryBalanceService.findSingleResult();
				findSingleResult.setBalance(balance);
				findSingleResult.setSedimentary(sedimentary);
				this.sedimentaryBalanceService.failBack(findSingleResult,changeRecord);
			}catch(Exception e){
				e.printStackTrace();//交易失败回退异常
				log.info("orderNo:"+order.getOrderNo()+",交易失败，回退异常，"+e.getMessage());
				jedis.decrBy("balance", changeRecord.getBalanceChange());
				jedis.incrBy("sedimentary", changeRecord.getSedimentaryChange());
			}finally{
//				jedisUtil.closeJedis(jedis);
				if(jedis != null) jedis.close();
			}
		}
	}

	/**
	 * 处理支付失败的订单
	 * @param activity
	 * @param list
	 */
	private void dealFailOrder(Activity activity,String orderNo) {
		if(activity != null && activity.getActivityItem() != null && activity.getActivityItem().size()>0){
			for(ActivityItem activityItem : activity.getActivityItem()){
				if(ActivityType.CGDZ.getType().equals(activityItem.getSubType())){//常规打折活动项
//					Jedis jedis = jedisUtil.getJedis();
					Jedis jedis = jedisPoolUtil.getJedis();
					try{
						OrderDetail detail = this.orderDetailService.findByOrderNoAndItemId(orderNo,activityItem.getId());
						if(detail != null){
							String key = ActivityUtil.getCgdzActivityKey(activity.getId());
							Long decrBy = jedis.decrBy(key, 1);//将常规打折活动的笔数减回去
							log.info("满减优惠1订单支付失败笔数回退:key"+key+",val:"+decrBy);
						}
					}catch(Exception e){
						e.printStackTrace();
					}finally{
//						jedisUtil.closeJedis(jedis);
						if(jedis != null) jedis.close();
					}
				}else if(ActivityType.MJ1.getType().equals(activityItem.getSubType())){
//					Jedis jedis = jedisUtil.getJedis();
					Jedis jedis = jedisPoolUtil.getJedis();
					try{
						OrderDetail detail = this.orderDetailService.findByOrderNoAndItemId(orderNo,activityItem.getId());
						if(detail != null){
							String key = ActivityUtil.getMjActivityKey(activity.getId());
							Long decrBy = jedis.decrBy(key, 1);//将常规打折活动的笔数减回去
							log.info("满减优惠1订单支付失败笔数回退:key"+key+",val:"+decrBy);
						}
					}catch(Exception e){
						e.printStackTrace();
					}finally{
//						jedisUtil.closeJedis(jedis);
						if(jedis != null) jedis.close();
					}
				}
			}
		}
		// 修改代金券状态
	}

	/**
	 * 电子卡售卡订单定时检查
	 * @Title: checkSaleCard  
	 * @Description:  
	 * @param saleCardList
	 * @throws
	 */
	private void checkSaleCard(List<DTOSaleCardOrder> saleCardList) {
		if(saleCardList == null || saleCardList.size() <= 0) return ;
		for(DTOSaleCardOrder orderDto : saleCardList) {
			String swiftNumber = orderDto.getSwiftNumber();
			if (StringUtil.isNotEmpty(swiftNumber)) {
				SearchRecgPayInfoForm form = new SearchRecgPayInfoForm();
				form.setSwiftNumber(swiftNumber);
				try {
					SearchRecgPayInfoReceive searchRecgPayInfoReceive = postConnServerNew.getResultData(form, RouteFinalValue.APP_RechargeQuery, SearchRecgPayInfoReceive.class);//根据微信订单号查询微信支付结果
					if(searchRecgPayInfoReceive == null){
						checkSaleCardOrder(orderDto);
						continue;
					}
					String payStatus = searchRecgPayInfoReceive.getTradeState();//微信支付状态
					if(PayStatus.Unpay.equals(payStatus)){//微信未支付
						checkSaleCardOrder(orderDto);
					}else if(PayStatus.Payed.equals(payStatus)){//微信支付成功
						//先查询售卡状态，如果成功了，返回成功
						CoreQuerySaleCardOut out2 = postConnServerNew.querySellECards(orderDto.getOrderNo(), merchantId);
						if(out2 == null) {//调用核心
							log.info("调用核心批量售电子卡状态查询接口异常");
							continue;
						}
						if(out2.getTaskState() == null) {//表示核心返回结果为空，也就是说订单不存在
							log.info("调用核心批量售电子卡状态查询结果为空");
							continue;
						}
						if(SaleCardStateEnum.SUCCESS.equals(out2.getTaskState())) {//查询到售卡状态为成功了
							//修改订单状态
							String tranEndTime = DateUtil.dateTimeToString(new Date());
							orderDto.setTradeEndTime(DateUtil.dateTimeToString(new Date()));
							orderDto.setOrderStatus(OrderStatus.Payed.getStatus());
							this.orderService.saveOrUpdate(orderDto);
							DTOSaleCardOrderDetail orderDetailDto = this.saleCardOrderDetailService.findDTOByOrderNo(orderDto.getOrderNo());
							orderDetailDto.setCards(out2.getSelledEcards());
							this.saleCardOrderDetailService.saveOrUpdate(orderDetailDto);
							//绑卡
							bindECard(orderDto.getAccId(), orderDetailDto.getDenomination(), out2.getSelledEcards());
							//存交易记录，发微信交易提醒
							DTOSaleCardRecord recordDto = transferSaleCardOrderToRecord(orderDto);
							recordDto.setTradeEndTime(tranEndTime);
							TradeRecord saleCardRecord2 = this.tradeRecordService.saveOrUpdate(recordDto);
							if (saleCardRecord2 == null) {
								log.info("批量售卡订单保存异常");
								continue;
							}
							sendSaleCardWxMessage(orderDto);//发送购卡的微信消息
						}
					}
				}catch(Exception e){
					e.printStackTrace();
					log.info("orderNo:" + orderDto.getOrderNo() + ",error:"+ e.getMessage());
				}
			}
		}
	}

	private void checkSaleCardOrder(DTOSaleCardOrder order) {
		CheckOrderRecord checkRecord = checkOrderRecordService.findByOrderNo(order.getOrderNo());
		if(checkRecord == null){
			checkRecord = new CheckOrderRecord();
			checkRecord.setCheckCount(1);
			checkRecord.setCheckTime(DateUtil.dateTimeToString(new Date()));
			checkRecord.setId(CommonUtils.getUUID());
			checkRecord.setOrderNo(order.getOrderNo());
			try {
				checkOrderRecordService.saveOrUpdate(checkRecord);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}else{
			if(checkRecord.getCheckCount() >= COUNT_LIMIT){//次数大于等于3，处理为失败
				order.setPayStatus(PayStatus.Unpay.getStatus());//微信未支付
				order.setOrderStatus(OrderStatus.PayFail.getStatus());//订单交易失败
				order.setUpdateTime(DateUtil.dateTimeToString(new Date()));
				order.setRemark(OrderScheduleErrMsg.getErrMsg(OrderScheduleErrMsg.PAY_FAIL));
				try {
					this.orderService.saveOrUpdate(order);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}else{
				checkRecord.setCheckTime(DateUtil.dateTimeToString(new Date()));
				checkRecord.setCheckCount(checkRecord.getCheckCount()+1);
				try {
					checkOrderRecordService.saveOrUpdate(checkRecord);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * 发送微信消息
	 * @Title: sendWxMessage  
	 * @Description:  
	 * @param orderDto
	 * @throws
	 */
	private void sendSaleCardWxMessage(DTOSaleCardOrder orderDto) {
		Account account = this.accountService.findById(orderDto.getAccId());
		JSONObject remindData = new JSONObject();
		remindData.put("openIdStr", account.getOpenId());
		remindData.put("modelType", "1");
		remindData.put("payValue", "￥" + orderDto.getRealPay() / 100.0);
		remindData.put("cardNo", orderDto.getCardNo());
		remindData.put("tranSno", orderDto.getOrderNo());
		remindData.put("tranTime", orderDto.getTradeEndTime());
		remindData.put("mrchName", orderDto.getMrchName());
		remindData.put("first", CommonConstants.FIRST_3);
		remindData.put("remark", CommonConstants.REMARK_1);
		TradeRemindThread tradeRemind = new TradeRemindThread(remindData);
		Thread thread = new Thread(tradeRemind);
		thread.start();
	}	
	/**
	 * 绑定电子卡
	 * @Title: bindECard  
	 * @Description:  
	 * @param orderDto
	 * @param out
	 * @param cardIds
	 * @throws
	 */
	private void bindECard(String accId, Long rechargeAmt, String cardIds) throws Exception{
		String[] cardArr = cardIds.split(",");
		for(String cardNo : cardArr) {
			AccECard accECard = new AccECard();
			accECard.setAccId(accId);
//			accECard.setAccNo(accNo);
			accECard.setCardMark(CardMarkConstant.ELEC_CARD);
			accECard.setCardNo(cardNo);
			accECard.setId(CommonUtils.getUUID());
			accECard.setFaceValue(rechargeAmt);
//			accECard.setExpiryDate(expiryDate);TODO 需要指定过期时间
			accECard.setIsDeleted(false);
			accECard.setCreateTime(DateUtil.dateTimeToString(new Date()));
			accECard.setCreator(accId);
			accECard.setRemark(null);
			accECard.setStatus(ECardStatus.NORMAL);
			accECard.setUpdater(accId);
			accECard.setUpdateTime(DateUtil.dateTimeToString(new Date()));
			this.accECardService.saveOrUpdate(accECard);
		}
	}
	
	/**
	 * 根据购卡订单对象装配购卡交易记录对象
	 * @Title: transferSaleCardOrderToRecord  
	 * @Description:  
	 * @param saleCardOrder
	 * @return
	 * @throws
	 */
	private DTOSaleCardRecord transferSaleCardOrderToRecord(DTOSaleCardOrder saleCardOrder) {
		DTOSaleCardRecord record = new DTOSaleCardRecord();
		BeanUtils.copyProperties(saleCardOrder, record);
		return record;
	}
}